From dc8499433a8f7dcbd38e75352a64a54128d592c0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 17:01:38 +0100 Subject: [PATCH] Refactor domain/vcpu allocation to be more separated. Signed-off-by: Keir Fraser --- xen/arch/x86/domain_build.c | 2 +- xen/common/dom0_ops.c | 12 +++++++++--- xen/common/domain.c | 19 +++++++++---------- xen/common/schedule.c | 35 ++++++++++++----------------------- xen/include/xen/sched.h | 3 ++- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index bf8129a572..69b0ddd58b 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -560,7 +560,7 @@ int construct_dom0(struct domain *d, d->shared_info->n_vcpu = num_online_cpus(); for ( i = 1; i < d->shared_info->n_vcpu; i++ ) - (void)alloc_vcpu(d, i); + (void)alloc_vcpu(d, i, i % num_online_cpus()); /* Set up monitor table */ update_pagetables(v); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index e6ffa59438..458255d3db 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -224,7 +224,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_MAX_VCPUS: { struct domain *d; - unsigned int i, max = op->u.max_vcpus.max; + unsigned int i, max = op->u.max_vcpus.max, cpu; ret = -EINVAL; if ( max > MAX_VIRT_CPUS ) @@ -250,8 +250,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = -ENOMEM; for ( i = 0; i < max; i++ ) - if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) ) - goto maxvcpu_out; + { + if ( d->vcpu[i] == NULL ) + { + cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus(); + if ( alloc_vcpu(d, i, cpu) == NULL ) + goto maxvcpu_out; + } + } ret = 0; diff --git a/xen/common/domain.c b/xen/common/domain.c index 1627c97a75..96c3b0a083 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -36,16 +36,11 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) if ( (d = alloc_domain()) == NULL ) return NULL; - v = d->vcpu[0]; + d->domain_id = dom_id; atomic_set(&d->refcnt, 1); - atomic_set(&v->pausecnt, 0); - - d->domain_id = dom_id; - v->processor = cpu; spin_lock_init(&d->big_lock); - spin_lock_init(&d->page_alloc_lock); INIT_LIST_HEAD(&d->page_list); INIT_LIST_HEAD(&d->xenpage_list); @@ -63,10 +58,16 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) return NULL; } + if ( (v = alloc_vcpu(d, 0, cpu)) == NULL ) + { + grant_table_destroy(d); + evtchn_destroy(d); + free_domain(d); + return NULL; + } + arch_do_createdomain(v); - sched_add_domain(v); - if ( !is_idle_task(d) ) { write_lock(&domlist_lock); @@ -370,8 +371,6 @@ int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) if ( (rc = arch_set_info_guest(v, ctxt)) != 0 ) return rc; - sched_add_domain(v); - return rc; } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index e45c7f6582..4c58a8d68e 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -93,7 +93,8 @@ void free_domain(struct domain *d) xfree(d); } -struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) +struct vcpu *alloc_vcpu( + struct domain *d, unsigned int vcpu_id, unsigned int cpu_id) { struct vcpu *v; @@ -104,6 +105,7 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) v->domain = d; v->vcpu_id = vcpu_id; + v->processor = cpu_id; atomic_set(&v->pausecnt, 0); v->cpumap = CPUMAP_RUNANYWHERE; @@ -116,18 +118,14 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) return NULL; } - if ( vcpu_id == 0 ) - return v; + sched_add_domain(v); - v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; - - d->vcpu[v->vcpu_id-1]->next_in_list = v; - - v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus(); - if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) ) - set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); - - set_bit(_VCPUF_down, &v->vcpu_flags); + if ( vcpu_id != 0 ) + { + v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; + d->vcpu[v->vcpu_id-1]->next_in_list = v; + set_bit(_VCPUF_down, &v->vcpu_flags); + } return v; } @@ -136,19 +134,10 @@ struct domain *alloc_domain(void) { struct domain *d; - if ( (d = xmalloc(struct domain)) == NULL ) - return NULL; - - memset(d, 0, sizeof(*d)); - - if ( alloc_vcpu(d, 0) == NULL ) - goto out; + if ( (d = xmalloc(struct domain)) != NULL ) + memset(d, 0, sizeof(*d)); return d; - - out: - xfree(d); - return NULL; } /* diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 61ae51c576..6f8a43d384 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -167,7 +167,8 @@ extern struct vcpu *idle_task[NR_CPUS]; #define IDLE_DOMAIN_ID (0x7FFFU) #define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags)) -struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id); +struct vcpu *alloc_vcpu( + struct domain *d, unsigned int vcpu_id, unsigned int cpu_id); struct domain *alloc_domain(void); void free_domain(struct domain *d); -- 2.30.2